package com.kookapi.asserts.register;


import com.kookapi.asserts.AssertionComponent;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author bairimengchang
 * @version 1.0
 * @project java-test
 * @description 自定义组件扫描器，负责管理和查找断言组件
 * @date 2025/9/29
 */
@Component
public class AssertionComponentRegistry implements ApplicationContextAware {

    private ApplicationContext applicationContext;

    /**
     * 断言组件缓存 Map<组件名称, 组件实例>
     */
    private final Map<String, AssertionComponent> componentMap = new ConcurrentHashMap<>();

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
        initComponents();
    }

    /**
     * 初始化时扫描所有断言组件
     */
    private void initComponents() {
        // 查找所有实现了AssertionComponent接口的Bean
        Map<String, AssertionComponent> beans = applicationContext.getBeansOfType(AssertionComponent.class);

        for (Map.Entry<String, AssertionComponent> entry : beans.entrySet()) {
            String beanName = entry.getKey();
            AssertionComponent component = entry.getValue();

            // TODO 获取组件注解中的名称（可以加自定义注解，这样更方便管理）
//            Assertion annotation = component.getClass().getAnnotation(Assertion.class);
//            String componentName = (annotation != null) ? annotation.value() : beanName;

            // 使用Bean名称作为组件名称，先简单一点
            String componentName = beanName;

            componentMap.put(componentName, component);
            System.out.println("注册断言组件: " + componentName + " -> " + component.getClass().getSimpleName());
        }
    }

    /**
     * 根据组件名称获取断言组件
     */
    public AssertionComponent getComponent(String componentName) {
        AssertionComponent component = componentMap.get(componentName);
        if (component == null) {
            throw new IllegalArgumentException("未找到断言组件: " + componentName);
        }
        return component;
    }

    /**
     * 获取所有已注册的组件名称
     */
    public Set<String> getAvailableComponents() {
        return componentMap.keySet();
    }
}
